{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Anaconda3\\envs\\tf1.14\\lib\\site-packages\\tensorflow\\python\\framework\\dtypes.py:516: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint8 = np.dtype([(\"qint8\", np.int8, 1)])\n",
      "D:\\Anaconda3\\envs\\tf1.14\\lib\\site-packages\\tensorflow\\python\\framework\\dtypes.py:517: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_quint8 = np.dtype([(\"quint8\", np.uint8, 1)])\n",
      "D:\\Anaconda3\\envs\\tf1.14\\lib\\site-packages\\tensorflow\\python\\framework\\dtypes.py:518: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint16 = np.dtype([(\"qint16\", np.int16, 1)])\n",
      "D:\\Anaconda3\\envs\\tf1.14\\lib\\site-packages\\tensorflow\\python\\framework\\dtypes.py:519: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_quint16 = np.dtype([(\"quint16\", np.uint16, 1)])\n",
      "D:\\Anaconda3\\envs\\tf1.14\\lib\\site-packages\\tensorflow\\python\\framework\\dtypes.py:520: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint32 = np.dtype([(\"qint32\", np.int32, 1)])\n",
      "D:\\Anaconda3\\envs\\tf1.14\\lib\\site-packages\\tensorflow\\python\\framework\\dtypes.py:525: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  np_resource = np.dtype([(\"resource\", np.ubyte, 1)])\n",
      "D:\\Anaconda3\\envs\\tf1.14\\lib\\site-packages\\tensorboard\\compat\\tensorflow_stub\\dtypes.py:541: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint8 = np.dtype([(\"qint8\", np.int8, 1)])\n",
      "D:\\Anaconda3\\envs\\tf1.14\\lib\\site-packages\\tensorboard\\compat\\tensorflow_stub\\dtypes.py:542: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_quint8 = np.dtype([(\"quint8\", np.uint8, 1)])\n",
      "D:\\Anaconda3\\envs\\tf1.14\\lib\\site-packages\\tensorboard\\compat\\tensorflow_stub\\dtypes.py:543: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint16 = np.dtype([(\"qint16\", np.int16, 1)])\n",
      "D:\\Anaconda3\\envs\\tf1.14\\lib\\site-packages\\tensorboard\\compat\\tensorflow_stub\\dtypes.py:544: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_quint16 = np.dtype([(\"quint16\", np.uint16, 1)])\n",
      "D:\\Anaconda3\\envs\\tf1.14\\lib\\site-packages\\tensorboard\\compat\\tensorflow_stub\\dtypes.py:545: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  _np_qint32 = np.dtype([(\"qint32\", np.int32, 1)])\n",
      "D:\\Anaconda3\\envs\\tf1.14\\lib\\site-packages\\tensorboard\\compat\\tensorflow_stub\\dtypes.py:550: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n",
      "  np_resource = np.dtype([(\"resource\", np.ubyte, 1)])\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from tensorflow.examples.tutorials.mnist import input_data as input_data\n",
    "from matplotlib import pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "tf.logging.set_verbosity(tf.logging.INFO)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From <ipython-input-2-571ac230dbf2>:2: read_data_sets (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use alternatives such as official/mnist/dataset.py from tensorflow/models.\n",
      "WARNING:tensorflow:From D:\\Anaconda3\\envs\\tf1.14\\lib\\site-packages\\tensorflow\\contrib\\learn\\python\\learn\\datasets\\mnist.py:260: maybe_download (from tensorflow.contrib.learn.python.learn.datasets.base) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please write your own downloading logic.\n",
      "WARNING:tensorflow:From D:\\Anaconda3\\envs\\tf1.14\\lib\\site-packages\\tensorflow\\contrib\\learn\\python\\learn\\datasets\\mnist.py:262: extract_images (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use tf.data to implement this functionality.\n",
      "Extracting ./train-images-idx3-ubyte.gz\n",
      "WARNING:tensorflow:From D:\\Anaconda3\\envs\\tf1.14\\lib\\site-packages\\tensorflow\\contrib\\learn\\python\\learn\\datasets\\mnist.py:267: extract_labels (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use tf.data to implement this functionality.\n",
      "Extracting ./train-labels-idx1-ubyte.gz\n",
      "WARNING:tensorflow:From D:\\Anaconda3\\envs\\tf1.14\\lib\\site-packages\\tensorflow\\contrib\\learn\\python\\learn\\datasets\\mnist.py:110: dense_to_one_hot (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use tf.one_hot on tensors.\n",
      "Extracting ./t10k-images-idx3-ubyte.gz\n",
      "Extracting ./t10k-labels-idx1-ubyte.gz\n",
      "WARNING:tensorflow:From D:\\Anaconda3\\envs\\tf1.14\\lib\\site-packages\\tensorflow\\contrib\\learn\\python\\learn\\datasets\\mnist.py:290: DataSet.__init__ (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use alternatives such as official/mnist/dataset.py from tensorflow/models.\n"
     ]
    }
   ],
   "source": [
    "#导入MNIST图片数据集\n",
    "mnist = input_data.read_data_sets(\"./\",one_hot=True)\n",
    "#这里\"./\"意思是存于当前目录下\n",
    "\n",
    "#有可能会出现NameError: name 'input_data' is not defined\n",
    "#原因：这是由于导入工具库后没有使用正确别名的原因，只要加入as input_data即可。\n",
    "#解决：应改成如下代码：\n",
    "#import tensorflow.examples.tutorials.mnist.input_data as input_data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(55000, 784)\n",
      "(55000, 10)\n",
      "(5000, 784)\n",
      "(5000, 10)\n",
      "(10000, 784)\n",
      "(10000, 10)\n"
     ]
    }
   ],
   "source": [
    "print(mnist.train.images.shape)\n",
    "print(mnist.train.labels.shape)\n",
    "\n",
    "print(mnist.validation.images.shape)\n",
    "print(mnist.validation.labels.shape)\n",
    "\n",
    "print(mnist.test.images.shape)\n",
    "print(mnist.test.labels.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x576 with 16 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8,8))\n",
    "\n",
    "for idx in range(16):\n",
    "    plt.subplot(4, 4, idx + 1)\n",
    "    plt.axis('off')\n",
    "    plt.title(\"[{}]\".format(np.argmax(mnist.train.labels[idx])))\n",
    "    plt.imshow(mnist.train.images[idx].reshape((28, 28)))\n",
    "    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From <ipython-input-5-91f76403c340>:72: softmax_cross_entropy_with_logits (from tensorflow.python.ops.nn_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "\n",
      "Future major versions of TensorFlow will allow gradients to flow\n",
      "into the labels input on backprop by default.\n",
      "\n",
      "See `tf.nn.softmax_cross_entropy_with_logits_v2`.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "tf.reset_default_graph()#用于解决Python的控制台保存上次运行结束的变量，导致下面的权重变量无法创建的问题。\n",
    "#定义计算图\n",
    "batch_size = 200\n",
    "trainig_step = 8000\n",
    "x = tf.placeholder(tf.float32, [None, 784], name = 'x')\n",
    "y = tf.placeholder(tf.float32, [None, 10], name = 'y')\n",
    "learning_rate = tf.placeholder(tf.float32)\n",
    "'''\n",
    "#采用正态分布truncated_normal初始化数据\n",
    "def initialize(shape, stddev = 0.1):\n",
    "    return tf.truncated_normal(shape, stddev = 0.1)\n",
    "\n",
    "'''\n",
    "#我们采用xavier_initializer()方法对权重进行初始化\n",
    "#    xavier_initializer(\n",
    "#        uniform=True,   #uniform: 使用uniform或者normal分布来随机初始化。 \n",
    "#        seed=None,  #seed: 可以认为是用来生成随机数的seed  \n",
    "#       dtype=tf.float32) #dtype: 只支持浮点数。\n",
    "\n",
    "\n",
    "#另外我们对每一层权重添加了L2正则l2_regularizer\n",
    "#(1) #获得一个计算l2_regularization的函数。lmbd为可调的超参数。\n",
    "lmbd= 0.1                                                                             \n",
    "l2_regularizer = tf.contrib.layers.l2_regularizer(lmbd)\n",
    "\n",
    "\n",
    "#下面在原代码基础上增加三个隐层，每层的神经元的个数在原基础上做调整\n",
    "\n",
    "#(2)#在定义w_1, w_2, w_3时，把（1）中返回的函数传递给get_variable()函数。这样在tf执行的时候，会自动计算好各个权重矩阵的L2范数，并放到GraphKeys.REGULARIZATION_LOSSES中。\n",
    "\n",
    "#注意：\n",
    "#（a）tf是分别计算的各个权重矩阵L2范数，并不加总。最终需要加总。\n",
    "#（b）l2_loss()函数返回的时矩阵所有元素平方和的一半。\n",
    "L1_units_counts = 500\n",
    "w_1 = tf.get_variable(\"w1\", [784, L1_units_counts], initializer = tf.contrib.layers.xavier_initializer(seed = 1), regularizer = l2_regularizer)\n",
    "b_1 = tf.get_variable(\"b1\", [L1_units_counts], initializer = tf.zeros_initializer())\n",
    "\n",
    "#前向传播\n",
    "logits_1 = tf.matmul(x, w_1) + b_1\n",
    "output_1 = tf.nn.relu(logits_1)\n",
    "\n",
    "L2_units_counts = 400\n",
    "w_2 = tf.get_variable(\"w2\", [L1_units_counts, L2_units_counts], initializer = tf.contrib.layers.xavier_initializer(seed = 1), regularizer = l2_regularizer)\n",
    "b_2 = tf.get_variable(\"b2\", [L2_units_counts], initializer = tf.zeros_initializer())\n",
    "logits_2 = tf.matmul(output_1, w_2) + b_2\n",
    "output_2 = tf.nn.relu(logits_2)\n",
    "\n",
    "L3_units_counts = 250\n",
    "w_3 = tf.get_variable(\"w3\", [L2_units_counts, L3_units_counts], initializer = tf.contrib.layers.xavier_initializer(seed = 1), regularizer = l2_regularizer)\n",
    "b_3 = tf.get_variable(\"b3\", [L3_units_counts], initializer = tf.zeros_initializer())\n",
    "logits_3 = tf.matmul(output_2, w_3) + b_3\n",
    "output_3 = tf.nn.relu(logits_3)\n",
    "\n",
    "L4_units_counts = 100\n",
    "w_4 = tf.get_variable(\"w4\", [L3_units_counts, L4_units_counts], initializer = tf.contrib.layers.xavier_initializer(seed = 1), regularizer = l2_regularizer)\n",
    "b_4 = tf.get_variable(\"b4\", [L4_units_counts], initializer = tf.zeros_initializer())\n",
    "logits_4 = tf.matmul(output_3, w_4) + b_4\n",
    "output_4 = tf.nn.relu(logits_4)\n",
    "\n",
    "L5_units_counts = 10\n",
    "w_5 = tf.get_variable(\"w5\", [L4_units_counts, L5_units_counts], initializer = tf.contrib.layers.xavier_initializer(seed = 1), regularizer = l2_regularizer)\n",
    "b_5 = tf.get_variable(\"b5\", [L5_units_counts], initializer = tf.zeros_initializer())\n",
    "logits_5 = tf.matmul(output_4, w_5) + b_5\n",
    "logits = logits_5\n",
    "\n",
    "#（3）L2正则\n",
    "reg_set = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)\n",
    "l2_loss = tf.add_n(reg_set)/batch_size#在计算NN的最终cost的时候，将（2）中生成的L2范数加总到其中。注意：加总之后要除以样本空间的大小，即cost = compute_cost(Z3, Y) + l2_loss\n",
    "\n",
    "\n",
    "#（4）交叉熵损失\n",
    "cross_entropy_loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits = logits, labels = y))\n",
    "\n",
    "#（5）最终的cost代价函数\n",
    "cost = cross_entropy_loss + l2_loss\n",
    "\n",
    "optimizer = tf.train.GradientDescentOptimizer(learning_rate = learning_rate).minimize(cost)\n",
    "\n",
    "#（6）将输出的结果与正确结果进行对比，即可得到我们的网络输出结果的准确率。\n",
    "pred = tf.nn.softmax(logits)\n",
    "correct_pred = tf.equal(tf.math.argmax(pred,1),tf.math.argmax(y,1))\n",
    "accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))\n",
    "\n",
    "\n",
    "'''\n",
    "出现下面错误的解决思路：\n",
    "1.Variable w already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarScope? Originally defined at:\n",
    "\n",
    "    此错误是在调用get.variable()时里面的参数name问题。他一直说w_1,w_2...已存在直接用，不用重新创建或者创建的变量名重复\n",
    "\n",
    "    原因：Python的控制台会保存上次运行结束的变量。\n",
    "\n",
    "    解决方法1：重开一个控制台即可\n",
    "    解决方法2：在代码的开头加上一句\n",
    "\n",
    "    tf.reset_default_graph()\n",
    "\n",
    "2. Dimensions must be equal, but are 400 and 784 for 'MatMul_1' (op: 'MatMul') with input shapes: [?,400], [784,300].\n",
    "\n",
    "    \n",
    "    原因：在做矩阵乘法运算时参数值传递过程中出现的问题\n",
    "    解决：本程序创建了4个隐层，在每个隐层都要做前向传播tf.matmul()的矩阵运算来往后传播，做matmul运算的两个矩阵前一个矩阵的列数和后一个矩阵的行数一定要相同才能计算\n",
    "    所以：1.要检查参与运算的矩阵变量的x与w_1，output_1与w_2,...output_i与w_(i+1)是否满足做乘法的条件\n",
    "          2.要检查matul（）内参数的位置与格式是否正确\n",
    "\n",
    "'''\n",
    "saver = tf.train.Saver()#saver用于保存或恢复训练的模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "after 100 training steps, the loss is 0.349003, the validation accuracy is 0.8748\n",
      "after 200 training steps, the loss is 0.304305, the validation accuracy is 0.923\n",
      "after 300 training steps, the loss is 0.224709, the validation accuracy is 0.941\n",
      "after 400 training steps, the loss is 0.164122, the validation accuracy is 0.9524\n",
      "after 500 training steps, the loss is 0.221098, the validation accuracy is 0.9542\n",
      "after 600 training steps, the loss is 0.116893, the validation accuracy is 0.9588\n",
      "WARNING:tensorflow:From D:\\Anaconda3\\envs\\tf1.14\\lib\\site-packages\\tensorflow\\python\\training\\saver.py:960: remove_checkpoint (from tensorflow.python.training.checkpoint_management) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use standard file APIs to delete files with this prefix.\n",
      "after 700 training steps, the loss is 0.145901, the validation accuracy is 0.9632\n",
      "after 800 training steps, the loss is 0.119466, the validation accuracy is 0.9644\n",
      "after 900 training steps, the loss is 0.0773416, the validation accuracy is 0.965\n",
      "after 1000 training steps, the loss is 0.1029, the validation accuracy is 0.966\n",
      "after 1100 training steps, the loss is 0.0460469, the validation accuracy is 0.97\n",
      "after 1200 training steps, the loss is 0.0773321, the validation accuracy is 0.9702\n",
      "after 1300 training steps, the loss is 0.0960285, the validation accuracy is 0.9756\n",
      "after 1400 training steps, the loss is 0.0746626, the validation accuracy is 0.9734\n",
      "after 1500 training steps, the loss is 0.0796269, the validation accuracy is 0.9732\n",
      "after 1600 training steps, the loss is 0.0929289, the validation accuracy is 0.9736\n",
      "after 1700 training steps, the loss is 0.0757313, the validation accuracy is 0.9754\n",
      "after 1800 training steps, the loss is 0.066981, the validation accuracy is 0.9778\n",
      "after 1900 training steps, the loss is 0.0423466, the validation accuracy is 0.977\n",
      "after 2000 training steps, the loss is 0.0703211, the validation accuracy is 0.9788\n",
      "after 2100 training steps, the loss is 0.0566442, the validation accuracy is 0.9778\n",
      "after 2200 training steps, the loss is 0.0561207, the validation accuracy is 0.9778\n",
      "after 2300 training steps, the loss is 0.0552365, the validation accuracy is 0.9776\n",
      "after 2400 training steps, the loss is 0.0770416, the validation accuracy is 0.976\n",
      "after 2500 training steps, the loss is 0.0295123, the validation accuracy is 0.9798\n",
      "after 2600 training steps, the loss is 0.0493691, the validation accuracy is 0.9774\n",
      "after 2700 training steps, the loss is 0.0537503, the validation accuracy is 0.976\n",
      "after 2800 training steps, the loss is 0.0288982, the validation accuracy is 0.9788\n",
      "after 2900 training steps, the loss is 0.0743272, the validation accuracy is 0.9762\n",
      "after 3000 training steps, the loss is 0.0554352, the validation accuracy is 0.9788\n",
      "after 3100 training steps, the loss is 0.0658527, the validation accuracy is 0.9776\n",
      "after 3200 training steps, the loss is 0.0245069, the validation accuracy is 0.9776\n",
      "after 3300 training steps, the loss is 0.0256671, the validation accuracy is 0.9806\n",
      "after 3400 training steps, the loss is 0.0342805, the validation accuracy is 0.9794\n",
      "after 3500 training steps, the loss is 0.0183537, the validation accuracy is 0.9814\n",
      "after 3600 training steps, the loss is 0.012359, the validation accuracy is 0.9804\n",
      "after 3700 training steps, the loss is 0.011264, the validation accuracy is 0.9822\n",
      "after 3800 training steps, the loss is 0.0146549, the validation accuracy is 0.9828\n",
      "after 3900 training steps, the loss is 0.021751, the validation accuracy is 0.9804\n",
      "after 4000 training steps, the loss is 0.0140484, the validation accuracy is 0.98\n",
      "after 4100 training steps, the loss is 0.0351628, the validation accuracy is 0.9812\n",
      "after 4200 training steps, the loss is 0.01283, the validation accuracy is 0.9842\n",
      "after 4300 training steps, the loss is 0.0117103, the validation accuracy is 0.9812\n",
      "after 4400 training steps, the loss is 0.0213959, the validation accuracy is 0.9806\n",
      "after 4500 training steps, the loss is 0.00662646, the validation accuracy is 0.9812\n",
      "after 4600 training steps, the loss is 0.0178373, the validation accuracy is 0.977\n",
      "after 4700 training steps, the loss is 0.00934361, the validation accuracy is 0.981\n",
      "after 4800 training steps, the loss is 0.0113147, the validation accuracy is 0.9822\n",
      "after 4900 training steps, the loss is 0.00680213, the validation accuracy is 0.9826\n",
      "after 5000 training steps, the loss is 0.0130937, the validation accuracy is 0.982\n",
      "after 5100 training steps, the loss is 0.00652105, the validation accuracy is 0.9822\n",
      "after 5200 training steps, the loss is 0.0081081, the validation accuracy is 0.982\n",
      "after 5300 training steps, the loss is 0.0109044, the validation accuracy is 0.9826\n",
      "after 5400 training steps, the loss is 0.00410233, the validation accuracy is 0.9834\n",
      "after 5500 training steps, the loss is 0.00693671, the validation accuracy is 0.9816\n",
      "after 5600 training steps, the loss is 0.00354566, the validation accuracy is 0.9818\n",
      "after 5700 training steps, the loss is 0.00649426, the validation accuracy is 0.9818\n",
      "after 5800 training steps, the loss is 0.00799, the validation accuracy is 0.9826\n",
      "after 5900 training steps, the loss is 0.00559164, the validation accuracy is 0.9822\n",
      "after 6000 training steps, the loss is 0.0100652, the validation accuracy is 0.983\n",
      "after 6100 training steps, the loss is 0.0115668, the validation accuracy is 0.982\n",
      "after 6200 training steps, the loss is 0.00847965, the validation accuracy is 0.9828\n",
      "after 6300 training steps, the loss is 0.00791255, the validation accuracy is 0.9824\n",
      "after 6400 training steps, the loss is 0.0154174, the validation accuracy is 0.9818\n",
      "after 6500 training steps, the loss is 0.00686371, the validation accuracy is 0.9814\n",
      "after 6600 training steps, the loss is 0.00391881, the validation accuracy is 0.9818\n",
      "after 6700 training steps, the loss is 0.00658209, the validation accuracy is 0.9826\n",
      "after 6800 training steps, the loss is 0.0037581, the validation accuracy is 0.9822\n",
      "after 6900 training steps, the loss is 0.00437474, the validation accuracy is 0.9838\n",
      "after 7000 training steps, the loss is 0.00562028, the validation accuracy is 0.984\n",
      "after 7100 training steps, the loss is 0.0103185, the validation accuracy is 0.9828\n",
      "after 7200 training steps, the loss is 0.00407283, the validation accuracy is 0.9812\n",
      "after 7300 training steps, the loss is 0.00510016, the validation accuracy is 0.983\n",
      "after 7400 training steps, the loss is 0.0118559, the validation accuracy is 0.9818\n",
      "after 7500 training steps, the loss is 0.00461558, the validation accuracy is 0.9832\n",
      "after 7600 training steps, the loss is 0.00889148, the validation accuracy is 0.983\n",
      "after 7700 training steps, the loss is 0.00261102, the validation accuracy is 0.9828\n",
      "after 7800 training steps, the loss is 0.0057796, the validation accuracy is 0.9822\n",
      "after 7900 training steps, the loss is 0.00869707, the validation accuracy is 0.9822\n",
      "training is finished !\n",
      "The test accuracy is 0.9821\n"
     ]
    }
   ],
   "source": [
    "lr = 1.0#初始化一个学习率\n",
    "#创建一个会话session，并填入数据开始训练 \n",
    "with tf.Session() as sess:\n",
    "    sess.run(tf.global_variables_initializer())\n",
    "    \n",
    "    #定义验证集和测试集\n",
    "    validate_data = {x: mnist.validation.images, y:mnist.validation.labels}\n",
    "    test_data = {x: mnist.test.images, y: mnist.test.labels}\n",
    "    \n",
    "    #填入数据做训练\n",
    "    for i in range(trainig_step):\n",
    "         \n",
    "        #调整学习率\n",
    "        if trainig_step > 1500:\n",
    "            lr = 0.7\n",
    "        if trainig_step > 3500:\n",
    "            lr = 0.5\n",
    "        if trainig_step > 4500:\n",
    "            lr = 0.3\n",
    "        if trainig_step > 7000:\n",
    "            lr = 0.1\n",
    "        xs, ys = mnist.train.next_batch(batch_size)\n",
    "        _,loss = sess.run([optimizer, cross_entropy_loss], feed_dict = {x: xs, y: ys, learning_rate: lr})\n",
    "       \n",
    "        #每100训练打印一次损失值与验证准确率\n",
    "        if i > 0 and i % 100 ==0:\n",
    "            validate_accuracy = sess.run(accuracy, feed_dict = validate_data)\n",
    "            print(\"after %d training steps, the loss is %g, the validation accuracy is %g\" % (i, loss, validate_accuracy))\n",
    "            saver.save(sess,'./model.ckpt', global_step = i)#保存训练的模型与当前目录下，保存成model.ckpt格式，用于后面的测试\n",
    "    \n",
    "    \n",
    "    print(\"training is finished !\")\n",
    "    \n",
    "    #打印最终的测试准确率\n",
    "    acc = sess.run(accuracy, feed_dict = test_data)\n",
    "    print(\"The test accuracy is\", acc)\n",
    "    \n",
    "#注意：对于本段代码的运行可能会出现一些错误：ValueError: Cannot feed value of shape (100,) for Tensor 'y:0', which has shape '(?, 10)'\n",
    "#原因是没有对mnist数据进行独热编码OneHot，修改如下：\n",
    "#mnist = input_data.read_data_sets('./mnist', one_hot=True)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "model_checkpoint_path: \"./model.ckpt-7900\"\n",
      "all_model_checkpoint_paths: \"./model.ckpt-7500\"\n",
      "all_model_checkpoint_paths: \"./model.ckpt-7600\"\n",
      "all_model_checkpoint_paths: \"./model.ckpt-7700\"\n",
      "all_model_checkpoint_paths: \"./model.ckpt-7800\"\n",
      "all_model_checkpoint_paths: \"./model.ckpt-7900\"\n",
      "\n",
      "WARNING:tensorflow:From D:\\Anaconda3\\envs\\tf1.14\\lib\\site-packages\\tensorflow\\python\\training\\saver.py:1276: checkpoint_exists (from tensorflow.python.training.checkpoint_management) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use standard file APIs to check for files with this prefix.\n",
      "INFO:tensorflow:Restoring parameters from ./model.ckpt-7900\n",
      "Test Accuracy: 1.0\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x576 with 16 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#tf.train.get_checkpoint_state函数通过checkpoint文件找到文件名\n",
    "#tf.train.get_checkpoint_state(checkpoint_dir, latest_filename = None)\n",
    "#该函数返回的是checkpoint文件CheckpointState proto类型的内容，其中有model_checkpoint_path和all_model_checkpoint_paths两个属性。\n",
    "    #其中model_checkpoint_path保存了最新的tensorflow文星文件的文件名，all_model_checkpoint_paths则有未被删除的所有tensorflow模型文件的文件名\n",
    "with tf.Session() as sess:\n",
    "    ckpt = tf.train.get_checkpoint_state('./')#获取在训练模型中训练出来的ckpt模型\n",
    "    print(ckpt)\n",
    "   \n",
    "    if ckpt and ckpt.model_checkpoint_path:\n",
    "        \n",
    "        saver.restore(sess, ckpt.model_checkpoint_path)\n",
    "        #global_step = ckpt.model_checkpoint_paths.split('.')[-1].split('-')[-1]\n",
    "        \n",
    "        #测试准确率\n",
    "        final_pred, acc = sess.run([pred, accuracy], \n",
    "                                   feed_dict = {x: mnist.test.images[:16], \n",
    "                                                y: mnist.test.labels[:16]})\n",
    "        print(\"Test Accuracy:\", acc)\n",
    "        #print(final_pred[0:10])\n",
    "        \n",
    "        orders = np.squeeze(np.argsort(final_pred))\n",
    "        plt.figure(figsize = (8, 8))\n",
    "        #查看orders与final_pred的维度\n",
    "        #print(np.shape(orders))\n",
    "        #print(np.shape(final_pred))\n",
    "        \n",
    "        for idx in range(16):\n",
    "            order = orders[idx, :][-1]\n",
    "            prob = final_pred[idx, :][order]\n",
    "            plt.subplot(4, 4, idx + 1)\n",
    "            plt.axis('off')\n",
    "            plt.title('{}:[{}] - [{:.1f}%]'.format(np.argmax(mnist.test.labels[idx]), order, prob * 100))#np.argmax将前面进行独热编码的标签数组返回最大数（独热编码后的数组中最大数为1，其余都是0）的索引\n",
    "            plt.imshow(mnist.test.images[idx].reshape((28, 28)))#其中cmap参数可接受接受一个值（每个值代表一种配色方案，例如 cmap='binary'\n",
    "            \n",
    "      \n",
    "    else:\n",
    "        pass \n",
    "    \n",
    "\n",
    "   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
